/**
 * All rights Reserved, Designed By www.tydic.com
 * @Title: EasyPaySignUtil.java
 * @Package: com.example.down
 * @Description:
 * @author: wangtao
 * @date: 2019年10月15日 下午3:06:54
 */
package com.hlkj.pay.app.merchant.ext.impl.hnapay.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.merchant.ext.impl.hnapay.dto.req.CallbackRefundRequest;
import com.hlkj.pay.app.merchant.ext.impl.hnapay.dto.req.CallbackTradeRequest;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * @ClassName: GhPaySignUtil
 * @Description:
 * @author: wangtao
 * @date: 2019年10月15日 下午3:06:54
 */
public class HnapaySignUtil {
	private static String encodingCharset = "UTF-8";

	public static String toHex(byte input[]) {
		if (input == null)
			return null;
		StringBuffer output = new StringBuffer(input.length * 2);
		for (int i = 0; i < input.length; i++) {
			int current = input[i] & 0xff;
			if (current < 16)
				output.append("0");
			output.append(Integer.toString(current, 16));
		}

		return output.toString();
	}

	/**
	 * @param aValue
	 * @return
	 */
	public static String digest(String aValue) {
		aValue = aValue.trim();
		byte value[];
		try {
			value = aValue.getBytes(encodingCharset);
		} catch (UnsupportedEncodingException e) {
			value = aValue.getBytes();
		}
		MessageDigest md = null;
		try {
			md = MessageDigest.getInstance("SHA");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return null;
		}
		return toHex(md.digest(value));

	}

	public static String md5(String value, String charset) {
		MessageDigest md = null;
		try {
			byte[] data = value.getBytes(charset);
			md = MessageDigest.getInstance("MD5");
			byte[] digestData = md.digest(data);
			return toHex(digestData);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return null;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static String sign(Object o, String key) throws IllegalAccessException {
		if(o instanceof Map) {
			return sign((Map<String, Object>)o, key);
		}
		Map<String, Object> map = BeanUtil.beanToMap(o);
		return sign(map, key);
//		ArrayList<String> list = new ArrayList<String>();
//		Class cls = o.getClass();
//		Field[] fields = cls.getDeclaredFields();
//		for (Field f : fields) {
//			f.setAccessible(true);
//			if (f.get(o) != null && f.get(o) != "") {
//				list.add(f.getName() + "=" + f.get(o) + "&");
//			}
//		}
//		int size = list.size();
//		String [] arrayToSort = list.toArray(new String[size]);
//		Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
//		StringBuilder sb = new StringBuilder();
//		for(int i = 0; i < size; i ++) {
//			sb.append(arrayToSort[i]);
//		}
//		String result = sb.toString();
//		result += "key=" + key;
//		System.out.println("Sign Before MD5:" + result);
//		result = md5(result, encodingCharset).toUpperCase();
//		System.out.println("Sign Result:" + result);
//		return result;
	}

	public static String getSortJson(JSONObject obj){
		SortedMap map = new TreeMap();
		Set<String> keySet = obj.keySet();
		Iterator<String> it = keySet.iterator();
		while (it.hasNext()) {
			String key = it.next().toString();
			Object vlaue = obj.get(key);
			map.put(key, vlaue);
		}
		return JSONObject.toJSONString(map);
	}

	public static String sign(Map<String,Object> map, String key){
		ArrayList<String> list = new ArrayList<String>();
		for(Map.Entry<String,Object> entry:map.entrySet()){
			if(null != entry.getValue() && !"".equals(entry.getValue()) &&!"sign".equals(entry.getKey())){
				if(entry.getValue() instanceof JSONObject) {
					list.add(entry.getKey() + "=" + getSortJson((JSONObject) entry.getValue()) + "&");
				}else {
					list.add(entry.getKey() + "=" + entry.getValue() + "&");
				}
			}
		}
		int size = list.size();
		String [] arrayToSort = list.toArray(new String[size]);
		Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i < size; i ++) {
			sb.append(arrayToSort[i]);
		}
		String result = sb.toString();
		result += "key=" + key;
		System.out.println("Sign Before MD5:" + result);
		result = md5(result, encodingCharset).toLowerCase();
		System.out.println("Sign Result:" + result);
		return result;
	}

	/**
	 *
	 * @param map
	 * @param key
	 * @param notContains 不包含的签名字段
	 * @return
	 */
	public static String sign(Map<String,Object> map, String key, String... notContains){
		Map<String,Object> newMap = new HashMap<String,Object>();
		for(Map.Entry<String,Object> entry:map.entrySet()){
			boolean isContain = false;
			for(int i=0; i<notContains.length; i++) {
				if(entry.getKey().equals(notContains[i])) {
					isContain = true;
					break;
				}
			}
			if(!isContain) {
				newMap.put(entry.getKey(), entry.getValue());
			}
		}
		return sign(newMap, key);
	}

	public static long converDate(String dateStr) {
		DateTime dateTime = DateUtil.parse(dateStr);
		return dateTime.getTime();
	}

	public static void main(String[] args) throws IllegalAccessException {
		String dateStr = "{\"amount\":\"1000\",\"channelTradeNo\":\"2025051322001471561405051043\",\"outTradeNo\":\"D20250513134342340126208\",\"payTime\":\"2025-05-13T13:44:40+08:00\",\"platformTxNo\":\"20250513134343AWJZILV1\",\"sign\":\"249a0fffb70f5a56416d1e152c229157\",\"signType\":\"MD5\",\"status\":\"SUCCESS\"}";

		CallbackTradeRequest request = JSON.parseObject(dateStr, CallbackTradeRequest.class);
//		refundRequest.setMerchantNo("S07391748");
		HnapaySignUtil.sign(request, "hWqUNkyZKjXrX3dR1TFq3m5dE63LUMUv");
		System.out.println("原始：249a0fffb70f5a56416d1e152c229157");

		System.out.println("退款验签---------------------------------");
		dateStr = "{\"outRefundNo\":\"T20250513140016607642624\",\"outTradeNo\":\"D20250513134342340126208\",\"platformRefundNo\":\"20250513140016UYYVIACL\",\"platformTxNo\":\"20250513134343AWJZILV1\",\"refundAmount\":\"1000\",\"refundStatus\":\"REFUND_SUCCESS\",\"refundTime\":\"2025-05-13T14:00:19+08:00\",\"sign\":\"0c9f7ad3affafae087bdd31346a25db6\",\"signType\":\"MD5\"}";
		CallbackRefundRequest refundRequest = JsonUtils.parseObject(dateStr, CallbackRefundRequest.class);
		refundRequest.setVersion("");
		HnapaySignUtil.sign(refundRequest, "hWqUNkyZKjXrX3dR1TFq3m5dE63LUMUv");
		System.out.println("原始：0c9f7ad3affafae087bdd31346a25db6");
	}
}
